
#import "AppDelegate.h"
#import "UserDetailsViewController.h"
#import "TorrentListViewController.h"
#import "ServerListViewController.h"
#import "SearchViewController.h"
#import "SettingsViewController.h"
#import "LoginViewController.h"

@implementation AppDelegate

//
// main window
//
@synthesize window															= _window;

//
// tabbar controller
//
@synthesize tabBarController												= _tabBarController;

//
// entitlements
//
@synthesize entitlements													= _entitlements;

//
// device token
//
@synthesize deviceToken														= _deviceToken;

//
// dealloc
//
- (void)dealloc
{
	self.window																= nil;
	self.tabBarController													= nil;
	self.entitlements														= nil;
	self.deviceToken														= nil;
	
	[super dealloc];
}

//
// upload category filter
//
- (void)uploadCategoryFilterWithCallback:(AsyncHttpRequestFinishCallback)callback
{
	callback																= [[callback copy] autorelease];
	
	id uploadCategoryCallback = ^void(XmlRpcRequest* uploadCategoryRequest)
	{
		if(callback)
			callback(uploadCategoryRequest);
		
		[uploadCategoryRequest release];
	};
	
	XmlRpcRequest* uploadCategoryRequest									= [[XmlRpcRequest alloc] initWithMethod:@"category.upload"];
	NSMutableDictionary* uploadCategoryRequestParam							= [NSMutableDictionary dictionaryWithCapacity:5];
	UIDevice* device														= [UIDevice currentDevice];
	NSString* apsEnvironment												= [self.entitlements valueForKey:@"aps-environment"];
	NSMutableString* categoryFilter											= [NSMutableString string];
	DataCenter* dataCenter													= [DataCenter sharedDataCenter];
	for(NSDictionary* config in dataCenter.pushConfig.categoryFilter)
	{
		if([[config valueForKey:@"enabled"] boolValue])
			continue;
		
		if(!categoryFilter.length)
			[categoryFilter appendString:@","];
		
		[categoryFilter appendFormat:@"%u,", (uint32_t)[[config valueForKey:@"categoryId"] integerValue]];
	}

	[uploadCategoryRequestParam setValue:device.name forKey:@"deviceName"];
	[uploadCategoryRequestParam setValue:self.deviceToken forKey:@"deviceToken"];
	[uploadCategoryRequestParam setValue:[NSNumber numberWithBool:[apsEnvironment isEqualToString:@"development"]] forKey:@"devMode"];
	[uploadCategoryRequestParam setValue:categoryFilter forKey:@"categoryFilter"];
	[uploadCategoryRequestParam setValue:@"u2@dmhy" forKey:@"serviceName"];
	[uploadCategoryRequest addParameter:uploadCategoryRequestParam];
	NSURL* pushProviderRpcUrl												= [NSURL URLWithString:dataCenter.pushConfig.apnProvider];
	uploadCategoryRequest.protocol											= pushProviderRpcUrl.scheme;
	uploadCategoryRequest.domain											= pushProviderRpcUrl.host;
	uploadCategoryRequest.port												= [pushProviderRpcUrl.port integerValue];
	uploadCategoryRequest.relPath											= pushProviderRpcUrl.path;
	[uploadCategoryRequest startWithCallback:uploadCategoryCallback];
}

//
// refresh torrent list view
//
- (void)refreshTorrentListView
{
	TorrentListViewController* torrentListViewController					= [[[[self.tabBarController viewControllers] objectAtIndex:1] viewControllers] objectAtIndex:0];
	BOOL forceReload														= [torrentListViewController isViewLoaded];
	torrentListViewController.pageIndex										= 0;
	if(self.tabBarController.selectedIndex != 1)
		[self.tabBarController setSelectedIndex:1];
	
	[torrentListViewController.navigationController popToRootViewControllerAnimated:YES];
	
	if(forceReload)
		[torrentListViewController reloadTorrentList:nil];
}

//
// show login view
//
- (void)showLoginView:(BOOL)showTorrentListTab
{
	DataCenter* dataCenter													= [DataCenter sharedDataCenter];
	NexusClient* client														= [NexusClient sharedClient];
	UserDetailsViewController* userDetailsViewController					= [[[[self.tabBarController viewControllers] objectAtIndex:0] viewControllers] objectAtIndex:0];;
	
	//
	// get user passkey finished
	//
	id getUserPasskeyFinished = [[^void(GetUserPassKeyRequest* httpRequest)
	{
		[ActivityView removeView];
		if(httpRequest.response.statusCode == 200)
		{
			dataCenter.userId												= httpRequest.userId;
			dataCenter.passKey												= httpRequest.passKey;
			dataCenter.mailAddress											= httpRequest.mailAddress;
			[dataCenter saveUserInfo];
			if(showTorrentListTab)
				[self refreshTorrentListView];
			[userDetailsViewController reloadUserDetails:!showTorrentListTab];
		}
		else
		{
			NSString* message												= [httpRequest errorDescription];
			NSString* title													= NSLocalizedStringFromTable(@"Get User PassKey Failed", @"AppDelegate", nil);
			id onCancel = ^void()
			{
				[self showLoginView:showTorrentListTab];
			};
			
			[dataCenter invalidUserInfo];
			[UIAlertView alertViewWithTitle:title message:message cancel:NSLocalizedString(@"OK", nil) others:nil onDismiss:nil onCancel:onCancel];
		}
	} copy] autorelease];
	
	//
	// post login callback
	//
	id postLoginCallback = [[^void(PostLoginRequest* httpRequest)
	{
		if(httpRequest.response.statusCode == 302)
		{
			dataCenter.cookieNexusPhp										= httpRequest.cookieNexusPhp;
			dataCenter.mailAddress											= httpRequest.userName;
			client.cookieNexusPhp											= httpRequest.cookieNexusPhp;
			[[ActivityView currentView] updateText:NSLocalizedStringFromTable(@"Getting User PassKey", @"AppDelegate", nil)];
			[client getUserPassKeyWithCallback:getUserPasskeyFinished];
		}
		else
		{
			[ActivityView removeView];
			NSString* message												= [httpRequest errorDescription];
			NSString* title													= NSLocalizedStringFromTable(@"Login Failed", @"AppDelegate", nil);
			id onCancel = ^void()
			{
				[self showLoginView:showTorrentListTab];
			};
			
			[dataCenter invalidUserInfo];
			[UIAlertView alertViewWithTitle:title message:message cancel:NSLocalizedString(@"OK", nil) others:nil onDismiss:nil onCancel:onCancel];
		}
	} copy] autorelease];	 

	//
	// login callback
	//
	id loginCallback = ^void(NSString* userName, NSString* password, NSString* captcha, NSString* sessionId)
	{
		[self.tabBarController dismissModalViewControllerAnimated:YES];
		[ActivityView showActivityView:NSLocalizedStringFromTable(@"Posting Login", @"AppDelegate", nil) networking:YES];
		[client postLogin:userName password:password captcha:captcha sessionId:sessionId callback:postLoginCallback];
	};
	
	//
	// show login view controller
	//
	LoginViewController* loginViewController								= [[[LoginViewController alloc] init] autorelease];
	loginViewController.callback											= loginCallback;
	UINavigationController* loginNavigationController						= [[[UINavigationController alloc] initWithRootViewController:loginViewController] autorelease];
	[self.tabBarController presentModalViewController:loginNavigationController animated:YES];
}

//
// launching finished
//
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
	//
	// get entitlement
	//
	self.entitlements														= [[UIApplication sharedApplication] entitlements];
	
	//
	// check remote notification launch
	//
	NSDictionary* payload													= [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
	BOOL showTorrentListTab													= payload ? YES : NO;
	
	//
	// load database
	//
	DataCenter* dataCenter													= [DataCenter sharedDataCenter];
	[dataCenter loadDomain:@"u2.dmhy.org"];
	
	//
	// setup client
	//
	NexusClient* client														= [NexusClient sharedClient];
	client.domain															= dataCenter.domain;
	
	//
	// register APN
	//
	[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];
	
	//
	// create main window
	//
	self.window																= [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
	
	//
	// create user detail view controller
	//
	UserDetailsViewController* userDetailsViewController					= [[[UserDetailsViewController alloc] init] autorelease];
	
	//
	// create navigation controller
	//
	UINavigationController* userDetailNavigationController					= [[[UINavigationController alloc] initWithRootViewController:userDetailsViewController] autorelease];
	
	//
	// create torrent list view controller
	//
	TorrentListViewController* torrentListViewController					= [[[TorrentListViewController alloc] init] autorelease];
	
	//
	// create navigation controller
	//
	UINavigationController* torrentListNavigationController					= [[[UINavigationController alloc] initWithRootViewController:torrentListViewController] autorelease];
	
	//
	// create server list view controller
	//
	ServerListViewController* serverListViewController						= [[[ServerListViewController alloc] init] autorelease];
	
	//
	// create navigation controller
	//
	UINavigationController* serverListNavigationController					= [[[UINavigationController alloc] initWithRootViewController:serverListViewController] autorelease];
	
	//
	// create search view controller
	//
	SearchViewController* searchViewController								= [[[SearchViewController alloc] init] autorelease];
	
	//
	// create navigation controller
	//
	UINavigationController* searchNavigationController						= [[[UINavigationController alloc] initWithRootViewController:searchViewController] autorelease];
	
	//
	// create setting view controller
	//
	SettingsViewController* settingsViewController							= [[[SettingsViewController alloc] init] autorelease];
	
	//
	// create navigation controller
	//
	UINavigationController* settingsNavigationController					= [[[UINavigationController alloc] initWithRootViewController:settingsViewController] autorelease];
	
	//
	// create tabbar controller
	//
	self.tabBarController													= [[[UITabBarController alloc] init] autorelease];
	
	//
	// setup child view controllers
	//
	self.tabBarController.viewControllers									= [NSArray arrayWithObjects:userDetailNavigationController, torrentListNavigationController, searchNavigationController, serverListNavigationController, settingsNavigationController, nil];
	
	//
	// setup root controller
	//
	self.window.rootViewController											= self.tabBarController;
	
	//
	// show
	//
	[self.window makeKeyAndVisible];
	
	//
	// setup badge
	//
	if(payload)
		torrentListViewController.tabBarItem.badgeValue						= [NSString stringWithFormat:@"%@", [payload valueForKeyPath:@"aps.badge"]];
	
	//
	// get saved user id
	//
	if(dataCenter.cookieNexusPhp.length)
	{
		//
		// get user passkey finished
		//
		id getUserPasskeyFinished = ^void(GetUserPassKeyRequest* httpRequest)
		{
			[ActivityView removeView];
			if(httpRequest.error || httpRequest.response.statusCode != 200)
			{
				NSString* message											= [httpRequest errorDescription];
				NSString* title												= NSLocalizedStringFromTable(@"Checking User PassKey Failed", @"AppDelegate", nil);
				id onCancel = ^void()
				{
					[self showLoginView:showTorrentListTab];
				};
				
				[dataCenter invalidUserInfo];
				[UIAlertView alertViewWithTitle:title message:message cancel:NSLocalizedString(@"OK", nil) others:nil onDismiss:nil onCancel:onCancel];
			}
			else
			{
				dataCenter.passKey											= httpRequest.passKey;
				dataCenter.mailAddress										= httpRequest.mailAddress;
				[dataCenter saveUserInfo];
				if(showTorrentListTab)
					[self refreshTorrentListView];
				
				[userDetailsViewController reloadUserDetails:!showTorrentListTab];
			}
		};
		
		//
		// check saved user info
		//
		client.cookieNexusPhp												= dataCenter.cookieNexusPhp;
		[ActivityView showActivityView:NSLocalizedStringFromTable(@"Checking User PassKey", @"AppDelegate", nil) networking:YES];
		[client getUserPassKeyWithCallback:getUserPasskeyFinished];
	}
	else
	{
		[self showLoginView:showTorrentListTab];
	}
	
	return YES;
}

//
// register APN finished
//
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
	NSMutableString* deviceTokenString										= [NSMutableString stringWithCapacity:deviceToken.length * 2];
	uint8_t const* deviceTokenBuffer										= (uint8_t const*)deviceToken.bytes;
	for(int i = 0; i < deviceToken.length; i ++)
		[deviceTokenString appendFormat:@"%02x", deviceTokenBuffer[i]];
 
	self.deviceToken														= deviceTokenString;
	
	if([DataCenter sharedDataCenter].pushConfig.apnProvider.length)
		[self uploadCategoryFilterWithCallback:nil];
}

//
// register APN failed;
//
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
	
}

//
// recieved notification
//
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
	TorrentListViewController* torrentListViewController					= [[[[self.tabBarController viewControllers] objectAtIndex:1] viewControllers] objectAtIndex:0];
	torrentListViewController.tabBarItem.badgeValue							= [NSString stringWithFormat:@"%@", [userInfo valueForKeyPath:@"aps.badge"]];
	
	if(application.applicationState != UIApplicationStateActive)
		[self refreshTorrentListView];
}

@end
